package com.glamour.hlcity.modules.spider.parser.impl;

import java.util.ArrayList;
import java.util.List;

import org.htmlparser.NodeFilter;
import org.htmlparser.Parser;
import org.htmlparser.filters.NodeClassFilter;
import org.htmlparser.filters.OrFilter;
import org.htmlparser.nodes.RemarkNode;
import org.htmlparser.nodes.TagNode;
import org.htmlparser.nodes.TextNode;
import org.htmlparser.tags.BodyTag;
import org.htmlparser.tags.Div;
import org.htmlparser.tags.ImageTag;
import org.htmlparser.tags.LinkTag;
import org.htmlparser.tags.TableTag;
import org.htmlparser.util.IteratorImpl;
import org.htmlparser.util.NodeIterator;
import org.htmlparser.util.NodeList;
import org.htmlparser.util.ParserException;

import com.glamour.hlcity.common.model.LinkNode;
import com.glamour.hlcity.common.model.Node;
import com.glamour.hlcity.common.util.ListUtil;
import com.glamour.hlcity.module.dom.analysis.impl.HtmlDomAnalysis;
import com.glamour.hlcity.modules.spider.parser.DomParser;

public class HtmlDomParser implements DomParser {

	@Override
	public List<Node> parser(NodeList resourceList) {
		
		if (resourceList == null) {
			return ListUtil.emptyList();
		}
		List<Node> resultList = new ArrayList<Node>();
		LinkNode tempNode = new LinkNode();
		for (int i = 0; i < resourceList.size(); i++) {
			org.htmlparser.Node tag = resourceList.elementAt(i);
			if (tag instanceof LinkTag)// <a> 标签
			{
				LinkTag link = (LinkTag) tag;
				String linkUrl = link.getLink();
				String text = link.getLinkText();
				tempNode = new LinkNode();
				tempNode.setNodeType(Node.LINK_NODE_TYPE_HREF);
				tempNode.setNodeNo(linkUrl);
				tempNode.setText(text);
				resultList.add(tempNode);
			} else if (tag instanceof ImageTag)// <img> 标签
			{
				ImageTag image = (ImageTag) tag;
				tempNode = new LinkNode();
				tempNode.setNodeType(Node.LINK_NODE_TYPE_IMG);
				tempNode.setNodeNo(image.getImageURL());
				tempNode.setText(image.getText());
				resultList.add(tempNode);

			} else// <frame> 标签

			{
				String frame = tag.getText().toLowerCase();
				int start = frame.indexOf("src=");
				frame = frame.substring(start);
				int end = frame.indexOf(" ");
				if (end == -1)
					end = frame.indexOf(">");
				frame = frame.substring(5, end - 1);
				tempNode = new LinkNode();
				tempNode.setNodeType(Node.LINK_NODE_TYPE_FRAME);
				tempNode.setNodeNo(frame);
				tempNode.setText(frame);
				resultList.add(tempNode);

			}

		}
		return resultList;
	}

	@Override
	public NodeList analysis(String url) {

		// gb2312编码
		NodeList nodeList = analysis(url, HtmlDomAnalysis.ENCODING_GB2312);
		if (nodeList == null) {
			// gbk编码
			nodeList = analysis(url, HtmlDomAnalysis.ENCODING_GBK);
			if (nodeList == null) {
				// utf-8编码
				nodeList = analysis(url, HtmlDomAnalysis.ENCODING_UTF8);
			}
		}
		return nodeList;
	}

	/**
	 * 以特定编码分析网页
	 * 
	 * @param url
	 * @param encoding
	 * @return
	 */
	private NodeList analysis(String url, String encoding) {
		Parser parser;
		try {
			parser = new Parser(url);
			parser.setEncoding(encoding);
			NodeFilter frameFilter = new NodeFilter() {
				@Override
				public boolean accept(org.htmlparser.Node node) {
					if (node.getText().toLowerCase().startsWith("iframe src=")) {
						return true;
					} else
						return false;
				}
			};
			
			OrFilter rorFilter = new OrFilter(
					new NodeClassFilter(LinkTag.class), new NodeClassFilter(
							ImageTag.class));
			OrFilter linkFilter = new OrFilter(rorFilter, frameFilter);
			return parser.extractAllNodesThatMatch(linkFilter);

		} catch (ParserException e) {
			e.printStackTrace();
		}

		return null;
	}

	public static void main(String[] strs) {
		Parser parser;
		try {
			parser = new Parser("e:\\test.html");
			for (NodeIterator i = parser.elements(); i.hasMoreNodes();)
				processMyNodes(i.nextNode());
		} catch (ParserException e) {
			e.printStackTrace();
		}

	}

	static void processMyNodes(org.htmlparser.Node node) {
		if (node instanceof TextNode) {
			// downcast to TextNode
			TextNode text = (TextNode) node;
			// do whatever processing you want with the text
			System.out.println(text.getText());
		}
		if (node instanceof RemarkNode) {
			// downcast to RemarkNode
			RemarkNode remark = (RemarkNode) node;
			// do whatever processing you want with the comment
		} else if (node instanceof TagNode) {
			// downcast to TagNode
			TagNode tag = (TagNode) node;
			// do whatever processing you want with the tag itself
			// ...
			// process recursively (nodes within nodes) via getChildren()
			NodeList nl = tag.getChildren();
			if (null != nl)
				try {
					for (NodeIterator i = nl.elements(); i.hasMoreNodes();)
						processMyNodes(i.nextNode());
				} catch (ParserException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}
	}

}
